<?php

namespace Xrfg\Api\Trading\Account\Controllers;

use App\Http\Controllers\Controller;
use App\Models\User;
use Exception;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Xrfg\Api\Trading\Home\Repositories\CoinPriceRepository;
use Xrfg\Core\Trading\Account\Models\Coin;
use Xrfg\Api\Trading\Account\Resources\AccountResource;
use Xrfg\Core\Trading\Account\Models\Account;
use Xrfg\Wallet\ETH\Services\ETHWallet;
use Xrfg\Wallet\TRX\Services\TRXWallet;
use Xrfg\Wallet\USDT\Services\USDTWallet;

class AccountController extends Controller
{
    /**
     * 币币账户列表.
     *
     * @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection|\Illuminate\Http\Response|AccountResource
     */
    public function index()
    {
        /** @var User $user */
        $user = Auth::user();
        $coins = Coin::whereIn('id', [1, 2])->get();
        $accounts = Account::where('user_id', $user->id)->whereIn('coin_id', [1, 2])->get();

        // 得到所拥有账户和所有币种的coin_id差集
        $diffIds = array_values(array_diff(
            $coins->pluck('id')->toArray(),
            $accounts->pluck('coin_id')->toArray()
        ));

        // 用户没有的账户创建生成
        foreach ($diffIds as $id) {
            $account = Account::firstOrCreate([
                'user_id' => $user->id,
                'coin_id' => $id,
            ]);
            $accounts->push($account->fresh());
        }

        // 生成钱包地址
        if (!app()->isLocal()) {
            foreach ($accounts as $account) {
                $coin = $coins->where('id', $account->coin_id)->first();
                if (!$account->address) {
                    $address = null;
                    $tag = null;
                    try {
                        switch ($coin->chain_type) {
                            case 'omnilayer':
                                // 生成OMNI地址
                                $address = (new USDTWallet())->newAccount($user);
                                break;
                            case 'ethereum':
                                $ids = $coins->where('chain_type', 'ethereum')->pluck('id')->toArray();
                                $address = optional($accounts->whereIn('coin_id', $ids)->where('address', '!=', null)->first())->address;
                                if (!$address) {
                                    $address = (new ETHWallet(config('wallet.eth.node.wallet')))->newAccount($user);
                                }
                                break;
                            case 'tron':
                                $ids = $coins->where('chain_type', 'tron')->pluck('id')->toArray();
                                $address = optional($accounts->whereIn('coin_id', $ids)->where('address', '!=', null)->first())->address;
                                if (!$address) {
                                    $address = (new TRXWallet(config('wallet.trx.node.wallet')))->newAccount();
                                }
                                break;
                            default:
                                break;
                        }
                        if ($address) {
                            $account->address = $address;
                            $account->tag = $tag;
                            $account->save();
                        }
                    } catch (Exception $exception) {
                        Log::error($exception);
                    }
                }
            }
        }

        $coinName = request('coin_name'); // USDT或USDT,BTC
        if ($coinName) { // 单个币种余额
            $coinNames = explode(',', $coinName);
            foreach ($coinNames as $k => $v) {
                $coinNames[$k] = strtoupper($v);
            }
            $accounts = Account::where('user_id', $user->id)
                ->whereIn('coin_id', Coin::whereIn('name', $coinNames)->pluck('id'))
                ->get();
            if (count($accounts) > 0) {
                $arr = [];
                foreach ($accounts as $account) {
                    $arr[$account->coin->name] = $account->load('coin');
                }
                return $this->array($arr);
            } else {
                return $this->array();
            }
        } else { // 所有币种余额
            return AccountResource::collection($accounts->load('coin'));
        }
    }

    /**
     * 币币资产估值.
     * @return \Illuminate\Http\Response
     */
    public function top()
    {
        $user = Auth::user();
        $coins = Coin::all();
        $accounts = Account::where('user_id', $user->id)->get();
        $total = 0; // 币币资产估值
        foreach ($accounts as $account) {
            $number = bcadd($account->available, $account->disabled);
            $coinName = $coins->where('id', $account->coin_id)->first()->name;
            $coin_to_usdt = (new CoinPriceRepository())->coinToUsdt($coinName);
            $number = bcmul($number, $coin_to_usdt);

            $total = bcadd($total, $number);
        }
        $total = bcadd($total, 0);

//        $usdt_to_cny = Cache::get('ticker:okex.com:otc:usdt')['price_cny'];
        $usdt_to_cny = 6.8;
        $total_cny = bcmul($total, $usdt_to_cny, 2);

        return $this->array([
            'total' => $total,
            'total_cny' => $total_cny
        ]);
    }
}
